﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Infrastructure;
using Infrastructure.Dao;
using ServiceStack;
using WsdShop.IService;
using WsdShop.Model;
using WsdShop.Model.Enum;
using WsdShop.Model.SearchModels;
using WsdShop.Model.ViewModels;
using SqlSugar;

namespace WsdShop.Service
{
    public class FreightService : IFreightService
    {
        private ICommonAreaService areaservice;
        public FreightService(ICommonAreaService _areaservice)
        {
            areaservice = _areaservice;
        }

        public List<FreightManageResponse> GetFreightManage(BaseSearchModel search, out int total)
        {
            var response = new List<FreightManageResponse>();
            var freight = BaseService.LoadPageEntities<FreightTemplate>(search.Skip, search.Take, out total, " 1=1 ", search.OrderByFields);
            if (freight != null && freight.Count > 0)
            {
                freight.ForEach(m => response.Add(m.ConvertTo<FreightManageResponse>()));
                response.ForEach(m => m.IsUsing = IsFreightTemplateUsing(m.Id));
                foreach (var item in response)
                {
                    var freightdetail = new List<FreightTemplateDetails>();
                    BaseService.LoadEntities<FreightTemplateDetail>(m => m.FreightTemplateId == item.Id).ForEach(n => freightdetail.Add(n.ConvertTo<FreightTemplateDetails>()));
                    freightdetail.ForEach(m => m.AreaNames = (m.AreaIds.FromJson<List<int>>().Contains(-1) ? new List<string> { "全国默认运费" } : areaservice.GetAreaListByIds(m.AreaIds.FromJson<List<int>>()).Select(s => s.Name).ToList()));
                    item.FreightDetail = freightdetail;
                }

            }
            return response;
        }

        private bool IsFreightTemplateUsing(int templateId)
        {
            using (var Db = DbConfig.GetInstance())
            {
                return Db.Queryable<Product>().Where(m => m.FreightTemplateId == templateId).Count() > 0;
            }
        }

        public Result DelFreight(int Id, int currentUserId)
        {
            var model = BaseService.LoadEntity<FreightTemplate>(m => m.Id == Id);
            if (model == null || model.Id == 0)
            {
                return Result.Failure("运费模版不存在");
            }

            model.IsDeleted = true;
            model.EditTime = DateTime.Now;
            model.EditUserId = currentUserId;
            if (BaseService.UpdateEntity(model))
            {
                return Result.Success();
            }
            return Result.Failure("操作失败");
        }

        public Result DelFreightDetail(int detailId, int currentUserId)
        {
            var model = BaseService.LoadEntity<FreightTemplateDetail>(m => m.Id == detailId);
            if (model == null || model.Id == 0)
            {
                return Result.Failure("运费模版不存在");
            }

            model.IsDeleted = true;
            model.EditTime = DateTime.Now;
            model.EditUserId = currentUserId;
            if (BaseService.UpdateEntity(model))
            {
                return Result.Success();
            }
            return Result.Failure("操作失败");
        }


        public Result EditFreightSubmit(FreightSave Freight, List<FreightDetailSave> FreightDetail, int currentUserId)
        {
            if (Freight == null || FreightDetail == null)
            {
                return Result.Failure("数据传入有误");
            }

            using (BaseService._db = DbConfig.GetInstance())
            {
                BaseService._db.CurrentFilterKey = "";

                //编辑
                if (Freight.TemplateId > 0)
                {
                    var freight = BaseService._db.Queryable<FreightTemplate>().SingleOrDefault(m => m.Id == Freight.TemplateId);
                    freight.FreightType = Freight.TemplateType;
                    freight.TemplateName = Freight.TemplateName;
                    freight.EditTime = DateTime.Now;
                    freight.EditUserId = currentUserId;

                    if (BaseService._db.Update(freight))
                    {
                        var origindetail = BaseService._db.Queryable<FreightTemplateDetail>().Where(m => m.FreightTemplateId == freight.Id).ToList();
                        origindetail.ForEach(m => { m.IsDeleted = true; m.EditTime = DateTime.Now; m.EditUserId = currentUserId; });
                        BaseService._db.UpdateRange(origindetail);
                        foreach (var item in FreightDetail)
                        {
                            if (item.detailId > 0)
                            {
                                var detailinfo = BaseService._db.Queryable<FreightTemplateDetail>().SingleOrDefault(m => m.Id == item.detailId);

                                if (Freight.TemplateType == EnumFreightTemplateType.无条件包邮.GetHashCode())
                                {
                                    detailinfo.FirstMoney = 0;
                                }
                                if (Freight.TemplateType == EnumFreightTemplateType.按重量.GetHashCode())
                                {
                                    detailinfo.FirstCount = item.data1;
                                    detailinfo.FirstMoney = item.data2;
                                    detailinfo.ContiCount = item.data3;
                                    detailinfo.ContiMoney = item.data4;
                                    detailinfo.FullCount = item.data5;

                                }
                                if (Freight.TemplateType == EnumFreightTemplateType.按地区.GetHashCode())
                                {
                                    detailinfo.FirstMoney = item.data1;
                                    detailinfo.FullCount = item.data2;
                                }
                                detailinfo.AreaIds = item.areas.ToJson();
                                detailinfo.IsDeleted = false;
                                detailinfo.EditTime = DateTime.Now;
                                detailinfo.EditUserId = currentUserId;
                                BaseService._db.Update(detailinfo);
                            }
                            else
                            {
                                FreightTemplateDetail updatedetail = new FreightTemplateDetail();
                                if (Freight.TemplateType == EnumFreightTemplateType.无条件包邮.GetHashCode())
                                {
                                    updatedetail.FirstMoney = 0;
                                }
                                if (Freight.TemplateType == EnumFreightTemplateType.按重量.GetHashCode())
                                {
                                    updatedetail.FirstCount = item.data1;
                                    updatedetail.FirstMoney = item.data2;
                                    updatedetail.ContiCount = item.data3;
                                    updatedetail.ContiMoney = item.data4;
                                    updatedetail.FullCount = item.data5;

                                }
                                if (Freight.TemplateType == EnumFreightTemplateType.按地区.GetHashCode())
                                {
                                    updatedetail.FirstMoney = item.data1;
                                    updatedetail.FullCount = item.data2;
                                }
                                updatedetail.AreaIds = item.areas.ToJson();
                                updatedetail.FreightTemplateId = freight.Id;
                                updatedetail.AddUserId = currentUserId;
                                BaseService._db.Insert(updatedetail);
                            }
                        }
                    }
                }
                //新增
                else
                {
                    var freight = new FreightTemplate();
                    freight.FreightType = Freight.TemplateType;
                    freight.TemplateName = Freight.TemplateName;
                    freight.AddUserId = currentUserId;
                    int freightid = BaseService._db.Insert(freight, true).ConvertTo<int>();
                    if (freightid > 0)
                    {
                        foreach (var item in FreightDetail)
                        {
                            FreightTemplateDetail updatedetail = new FreightTemplateDetail();
                            if (Freight.TemplateType == EnumFreightTemplateType.无条件包邮.GetHashCode())
                            {
                                updatedetail.FirstMoney = 0;
                            }
                            if (Freight.TemplateType == EnumFreightTemplateType.按重量.GetHashCode())
                            {
                                updatedetail.FirstCount = item.data1;
                                updatedetail.FirstMoney = item.data2;
                                updatedetail.ContiCount = item.data3;
                                updatedetail.ContiMoney = item.data4;
                                updatedetail.FullCount = item.data5;

                            }
                            if (Freight.TemplateType == EnumFreightTemplateType.按地区.GetHashCode())
                            {
                                updatedetail.FirstMoney = item.data1;
                                updatedetail.FullCount = item.data2;
                            }
                            updatedetail.AreaIds = item.areas.ToJson();
                            updatedetail.FreightTemplateId = freightid;
                            updatedetail.AddUserId = currentUserId;
                            BaseService._db.Insert(updatedetail);
                        }
                    }
                }
                return Result.Success();
            }
        }


        public FreightResponse EditFreight(int Id)
        {
            FreightResponse response = new FreightResponse();
            if (Id > 0)
            {
                var freight = BaseService.LoadEntity<FreightTemplate>(m => m.Id == Id);
                response.TemplateId = freight.Id;
                response.TemplateName = freight.TemplateName;
                response.TemplateType = freight.FreightType;

                List<FreightDetailResponse> detaillist = new List<FreightDetailResponse>();

                var DetailList = BaseService.LoadEntities<FreightTemplateDetail>(m => m.FreightTemplateId == freight.Id);
                if (DetailList != null && DetailList.Count > 0)
                {
                    if (freight.FreightType == EnumFreightTemplateType.无条件包邮.GetHashCode())
                    {
                        detaillist.Add(new FreightDetailResponse { areas = new List<Common_Area> { new Common_Area { Id = -1, Name = "全国统一运费" } }, data1 = 0, detailId = DetailList.FirstOrDefault().Id });
                    }
                    if (freight.FreightType == EnumFreightTemplateType.按重量.GetHashCode())
                    {
                        foreach (var item in DetailList)
                        {
                            detaillist.Add(new FreightDetailResponse { areas = (item.AreaIds.FromJson<List<int>>().Contains(-1) ? new List<Common_Area> { new Common_Area { Id = -1, Name = "全国默认运费" } } : areaservice.GetAreaListByIds(item.AreaIds.FromJson<List<int>>())), data1 = item.FirstCount, data2 = item.FirstMoney, data3 = item.ContiCount, data4 = item.ContiMoney, data5 = item.FullCount, detailId = item.Id });
                        }
                    }
                    if (freight.FreightType == EnumFreightTemplateType.按地区.GetHashCode())
                    {
                        foreach (var item in DetailList)
                        {
                            detaillist.Add(new FreightDetailResponse { areas = (item.AreaIds.FromJson<List<int>>().Contains(-1) ? new List<Common_Area> { new Common_Area { Id = -1, Name = "全国默认运费" } } : areaservice.GetAreaListByIds(item.AreaIds.FromJson<List<int>>())), data1 = item.FirstMoney, data2 = item.FullCount, detailId = item.Id });
                        }
                    }

                }
                response.DetailResponse = detaillist;
            }
            else
            {
                response.TemplateId = 0;
                response.TemplateName = "";
                response.TemplateType = EnumFreightTemplateType.无条件包邮.GetHashCode();
                List<FreightDetailResponse> detaillist = new List<FreightDetailResponse>();
                detaillist.Add(new FreightDetailResponse { areas = new List<Common_Area> { new Common_Area { Id = -1, Name = "全国统一运费" } }, data1 = 0, detailId = 0 });
                response.DetailResponse = detaillist;
            }
            return response;
        }

        public List<FreightTemplate> GetFreightTemplateList()
        {
            using (var Db = DbConfig.GetInstance())
            {
                return Db.Queryable<FreightTemplate>().ToList();
            }
        }


        #region 计算运费

        public Result GetPostageMoney(List<CartProduct> products, string province, out decimal postMoney)
        {
            if (!province.IsNullOrEmpty())
            {
                var area = areaservice.GetArea(province, 1);
                if (area != null)
                {
                    return GetPostageMoney(products, area.Id, out postMoney);
                }
            }
            return GetPostageMoney(products, -1, out postMoney);
        }
        public Result GetPostageMoney(List<CartProduct> products, int areaId, out decimal postMoney)
        {
            using (var Db = DbConfig.GetInstance())
            {
                postMoney = 0;
                var templateGroup = products.Where(e => e.FreightTemplateId > 0).GroupBy(e => e.FreightTemplateId);
                foreach (var group in templateGroup)
                {
                    var template = Db.Queryable<FreightTemplate>().SingleOrDefault(m => m.Id == group.Key);
                    if (template == null)
                    {
                        return Result.Failure("运费模版缺失");
                    }
                    var details = Db.Queryable<FreightTemplateDetail>().Where(m => m.FreightTemplateId == group.Key).ToList();
                    if (details==null || details.Count==0)
                    {
                        return Result.Failure("运费模版缺失");
                    }
                    var detail = details.FirstOrDefault(e => e.AreaIds.FromJson<List<int>>().Contains(areaId));
                    if (detail == null)
                        detail = details.FirstOrDefault(e => e.AreaIds.FromJson<List<int>>().Contains(-1));
                    if (detail == null && (EnumFreightTemplateType)template.FreightType != EnumFreightTemplateType.无条件包邮)
                        return Result.Failure("运费模版缺失");



                    switch ((EnumFreightTemplateType)template.FreightType)
                    {
                        case EnumFreightTemplateType.无条件包邮:

                            break;
                        case EnumFreightTemplateType.按地区:
                            var totalMoney = group.Sum(e => e.Num * e.Price);
                            if (totalMoney < detail.FullCount || detail.FullCount == 0)
                            {
                                postMoney += detail.FirstMoney;
                            }
                            break;
                        case EnumFreightTemplateType.按重量:
                            var weight = group.Sum(e => e.Num * e.ProductWeight);
                            if (weight > detail.FullCount || weight <= 0)
                            {
                                postMoney += detail.FirstMoney + (detail.ContiCount != 0 ? Math.Ceiling(Math.Max(0, (weight - detail.FirstCount)) / detail.ContiCount) * detail.ContiMoney : 0);
                            }
                            break;
                    }
                }
                postMoney += products.GroupBy(e => e.ProductSku).Sum(e => e.Max(p => p.UniformFreight));
                return Result.Success();
            }
        }

        public decimal GetPostageMoney(List<SpecResponse> products, int areaId)
        {
            using (var Db = DbConfig.GetInstance())
            {
                decimal postMoney = 0;
                var templateGroup = products.Where(e => e.FreightTemplateId > 0).GroupBy(e => e.FreightTemplateId);
                foreach (var group in templateGroup)
                {
                    var template = Db.Queryable<FreightTemplate>().SingleOrDefault(m => m.Id == group.Key);
                    if (template == null)
                    {
                        throw new Exception("运费模版缺失");
                    }
                    var details = Db.Queryable<FreightTemplateDetail>().Where(m => m.FreightTemplateId == group.Key).ToList();
                    if (details == null || details.Count == 0)
                    {
                        throw new Exception("运费模版缺失");
                    }
                    var detail = details.FirstOrDefault(e => e.AreaIds.FromJson<List<int>>().Contains(areaId));
                    if (detail == null)
                        detail = details.FirstOrDefault(e => e.AreaIds.FromJson<List<int>>().Contains(-1));
                    if (detail == null && (EnumFreightTemplateType)template.FreightType != EnumFreightTemplateType.无条件包邮)
                        throw new Exception("运费模版缺失");



                    switch ((EnumFreightTemplateType)template.FreightType)
                    {
                        case EnumFreightTemplateType.无条件包邮:

                            break;
                        case EnumFreightTemplateType.按地区:
                            var totalMoney = group.Sum(e => e.BuyCount * e.Price);
                            if (totalMoney < detail.FullCount || detail.FullCount == 0)
                            {
                                postMoney += detail.FirstMoney;
                            }
                            break;
                        case EnumFreightTemplateType.按重量:
                            var weight = group.Sum(e => e.BuyCount * e.ProductWeight);
                            if (weight > detail.FullCount || weight <= 0)
                            {
                                postMoney += detail.FirstMoney + (detail.ContiCount != 0 ? Math.Ceiling(Math.Max(0, (weight - detail.FirstCount)) / detail.ContiCount) * detail.ContiMoney : 0);
                            }
                            break;
                    }
                }
                postMoney += products.GroupBy(e => e.ProductSku).Sum(e => e.Max(p => p.UniformFreight));
                return postMoney;
            }
        }

        #endregion

    }
}
